package com.fengwk.support.config;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.fengwk.support.util.ArrayUtils;
import com.fengwk.support.util.BeanUtils;
import com.fengwk.support.util.CollectionUtils;
import com.fengwk.support.util.ObjectUtils;
import com.fengwk.support.util.TypeUtils;

/**
 * 抽象的配置类
 */
public abstract class AbstractContextConfig {
	
	/**
	 * 读取配置
	 * @return
	 */
	protected abstract List<? extends Config> read();
	
	/**
	 * 更新配置
	 */
	public void update() {
		inject();
	}
	
	/**
	 * 注入配置
	 */
	private void inject() {
		// 获取字段
		Field[] fields = this.getClass().getDeclaredFields();
		if(ArrayUtils.isBlank(fields)) {
			return;
		}
		// 获取配置
		List<? extends Config> configList = read();
		if(CollectionUtils.isBlank(configList)) {
			return;
		}
		// 注入
		for(int i = 0; i < fields.length; i ++) {
			Iterator<? extends Config> it = configList.iterator();
			while(it.hasNext()) {
				Config _config = it.next();
				if(BeanUtils.grantAccessible(fields[i]).getName().equals(_config.getKey())) {
					Class<?> fieldType = fields[i].getType();
					if(TypeUtils.isCollection(fieldType)) {
						if(TypeUtils.isList(fieldType)) {
							injectWithList(fields[i], _config);
						} else if (TypeUtils.isSet(fieldType)) {
							injectWithSet(fields[i], _config);
						}
					}
					try {
						fields[i].set(this, buildValue(fields[i], _config));
					} catch (IllegalArgumentException | IllegalAccessException e) {
						e.printStackTrace();
					}
					break;
				}
			}
		}
	}

	// List注入
	private void injectWithList(Field field, Config config) {
		injectWithCollection(field, config, List.class);
	}
	
	// Set注入
	private void injectWithSet(Field field, Config config) {
		injectWithCollection(field, config, Set.class);
	}
	
	// 集合注入
	@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
	private void injectWithCollection(Field field, Config config, Class<? extends Collection> collectionClazz) {
		try {
			Collection collection = (Collection) field.get(this);
			if(CollectionUtils.isBlank(collection)) {
				collection = (Collection) ObjectUtils.build(collectionClazz);
				field.set(this, collection);
			}
			collection.add(buildValue(field, config));
		} catch (IllegalArgumentException | IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	
	// 构建配置值
	private Object buildValue(Field field, Config config) {
		return ObjectUtils.build(field.getType(), config.getValue());
	}
	
	/**
	 * Config key value 对象
	 */
	public static class Config implements Serializable {
		
		private static final long serialVersionUID = 9203386831063428333L;
		
		protected String key;// 键
		protected String value;// 值
		public String getKey() {
			return key;
		}
		public void setKey(String key) {
			this.key = key;
		}
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		
	}
	
}
